package com.applet.applet_shangcheng.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.applet.applet_shangcheng.utlis.*;
import com.github.wxpay.sdk.*;
import io.swagger.annotations.ApiOperation;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.applet.applet_shangcheng.utlis.AppletUtil.getRandomStringByLength;

/**
 * @author Administrator
 * @version 1.0
 **/

@Controller
public class WxPayController {

    String appID = "wx24e555c077e702f3";
    String mchID = "1582954481";
    String appSecret = "da2f185559d5d14e0d98ae268d7deb7b";
    String key = "washimayun1302525820515014354439";
    //申请授权码地址
    String wxOAuth2RequestUrl = "https://open.weixin.qq.com/connect/oauth2/authorize";
    //授权回调地址
    String wxOAuth2CodeReturnUrl = "http://www.weixin.qq.com/wxpay/pay.php";
    String state="";
    @RequestMapping("/notify")
    @ResponseBody
    public void notifyWxPay(HttpServletRequest request) throws Exception{
        System.out.println("进来了");
        ServletInputStream is = request.getInputStream();
        //ByteOutputStream os = new ByteOutputStream();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        byte[] arr = new byte[1024];
        int len;
        while((len=is.read())!=-1){
            os.write(arr,0,len);
        }
        os.flush();
        os.close();
        is.close();
        String strXml= new String(String.valueOf(os));
        System.out.println(strXml);
        Map<String, String> map = WXPayUtil.xmlToMap(strXml);
        System.out.println(map);
    }
    //获取授权码
    @GetMapping("/getWXOAuth2Code")
    public String getWXOAuth2Code(HttpServletRequest request, HttpServletResponse response){

        //https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
        String url = String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect",
                appID, wxOAuth2CodeReturnUrl
        );
        return "redirect:"+url;

    }
//    @RequestMapping(value = "/getOpenid", method = RequestMethod.POST)
    @PostMapping("/getOpenid")
    @ResponseBody
    public Map<String,String> decodeUserInfo(@RequestParam("code") String code) {
        // 登录凭证不能为空
        Map<String,String> map =new HashMap<>();
        if (code == null || code.length() == 0) {
            map.put("code","code 不能为空");
            return map;
        }
        //向微信服务器 使用登录凭证 code 获取 session_key 和 openid
        // 请求参数
        String params = "appid=" + appID + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";

        // 发送请求
        String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);

        JSONObject jsonObject = JSONObject.parseObject(sr);

        System.out.println(jsonObject.get("openid"));

        map.put("message","成功");
        map.put("openid", (String) jsonObject.get("openid"));
        return map;
    }

    /**
     * //授权码回调，传入授权码和state，/wx-oauth-code-return?code=授权码&state=
     * @param code 授权码
     * @return
     */
    @GetMapping("/wx-oauth-code-return/{code}")
    public String wxOAuth2CodeReturn(@PathVariable("code") String code){
        //https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                appID, appSecret, code
        );
        //申请openid，请求url
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        //申请openid接口响应的内容，其中包括了openid
        String body = exchange.getBody();
        //log.info("申请openid响应的内容:{}",body);
        //获取openid
        String openid = JSON.parseObject(body).getString("openid");
        //重定向到统一下单接口
        return "redirect:http://xfc.nat300.top/transaction/wxjspay?openid=" + openid;
    }
    //统一下单，接收openid
    @ApiOperation(value="创建订单order_id/订单号")
    @GetMapping("/wxjspay/{order_id}/{unit_price}")
    @ResponseBody
    public  Map<String, Object>  wxjspay(@PathVariable("order_id") String order_id,
                                @PathVariable("unit_price")  String unit_price, HttpServletRequest request) throws Exception {
        String pay_url = WXConstVO.pay_url;
        //入参,将数据封装到map转xml
        Map<String,String>data= new HashMap<>();
        data.put("appid", WXConstVO.appId);// 小程序ID
        data.put("mch_id", WXConstVO.mch_id);// 商户号
        data.put("nonce_str", WXPayUtil.generateNonceStr());// 随机字符串
        data.put("body", "小程序支付");              //商品描述
        data.put("out_trade_no", order_id);         //商户订单号
        data.put("total_fee", unit_price);// 订单总金额，单位为分
        data.put("spbill_create_ip", AppletUtil.getIpAddr(request));//终端IP
        data.put("notify_url", wxOAuth2CodeReturnUrl);// 回调地址
        data.put("trade_type", "JSAPI");//交易类型NATIVE,JSAPI
        //data.put("openid", WXConstVO.);//用户标识
        data.put("openid", "oKbmB4k_N4bdggUI_95A1uDZbPLg");//用户标识
        String signedXml = WXPayUtil.generateSignedXml(data,WXConstVO.key);//xml

        System.out.println(order_id+"+"+unit_price);
        //请求:httpclient
        HttpClient httpClient = new HttpClient(pay_url);
        httpClient.setXmlParam(signedXml);//请求参数
        httpClient.setHttps(true);        //请求方式
        httpClient.post();

        //响应结果xml转map
        String strXml = httpClient.getContent();
        Map<String, String> map = WXPayUtil.xmlToMap(strXml);
        System.out.println(map);
        //String prepayId = map.get("prepay_id");
       // System.out.println(prepayId);

        //准备h5网页需要的数据
       /* Map<String,String> jsapiPayParam = new HashMap<>();
        jsapiPayParam.put("appId",appID);
        jsapiPayParam.put("timeStamp",System.currentTimeMillis()/1000+"");
        jsapiPayParam.put("nonceStr", UUID.randomUUID().toString());//随机字符串
//        jsapiPayParam.put("package","prepay_id="+resp.get("prepay_id"));
        jsapiPayParam.put("package","prepay_id="+prepayId);
         //将h5网页响应给前端

        jsapiPayParam.put("paySign", WXPayUtil.generateSignature(jsapiPayParam,key,WXPayConstants.SignType.HMACSHA256));*/
//        return new ModelAndView("wxpay",jsapiPayParam);
        String return_code = (String) map.get("return_code");//返回状态码
        String result_code = (String) map.get("result_code");//返回状态码
        //生成的随机字符串
        String nonce_str = getRandomStringByLength(32);
        Map<String, Object> response = new HashMap<String, Object>();//返回给小程序端需要的参数
     if (return_code .equals("SUCCESS")  && result_code.equals("SUCCESS")) {
            String prepay_id = (String) map.get("prepay_id");//返回的预付单信息
            response.put("nonceStr", nonce_str);
            response.put("resultCode", result_code);
            response.put("returnCode", return_code);
            response.put("package", "prepay_id=" + prepay_id);
            Long timeStamp = System.currentTimeMillis() / 1000;
            response.put("timeStamp", timeStamp + "");//这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
            //拼接签名需要的参数
            String stringSignTemp = "appId=" +appID + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + timeStamp;
            //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
            String paySign = PayUtil.sign(stringSignTemp, key, "utf-8").toUpperCase();
            response.put("paySign", paySign);
    }

        response.put("appid", appID);
        return response;
    }

/* demo: function () {
    let operFlag = 'pay';
    wx.request({
      url: 'http://localhost:8900/wxjspay/1233389254/1',
      data: {

      },
      header: { 'content-type': 'application/json' },
      success: function (res) {
        console.log(res);
        wx.requestPayment({
          'timeStamp': res.data.timeStamp,
          'nonceStr': res.data.nonceStr,
          'package': res.data.package,
          'signType': 'MD5',
          'paySign': res.data.paySign,
          'success': function (res) {
            if (res.errMsg == "requestPayment:ok") {
              wx.showToast({
                title: '支付成功'
              })
            }
          },
          'fail': function (res) {
          }
        })
      },*/
}
